package edu.zut.cs.software.teach.Base.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import edu.zut.cs.software.teach.Base.dao.GenericTreeDao;
import edu.zut.cs.software.teach.Base.domain.BaseTreeEntity;
import edu.zut.cs.software.teach.Base.service.GenericTreeManager;
import edu.zut.cs.software.teach.Base.service.impl.GenericManagerImpl;
/**
 * 
 * @author yuki
 *
 * @param <T>
 * @param <PK>
 */
@Transactional
public class GenericTreeManagerImpl<T extends BaseTreeEntity<T, PK>, PK extends Serializable>
		extends GenericManagerImpl<PK, T> implements GenericTreeManager<T, PK> {

	protected GenericTreeDao<T, PK> treeDao;

	
	@Override
	public T findById(PK smsId) {
		// TODO Auto-generated method stub
		return super.findById(smsId);
	}

	@Override
	public void deleteId(PK smsId) {
		// TODO Auto-generated method stub
		super.deleteId(smsId);
	}

	@Override
	public Iterable<T> save(Iterable<T> entities) {
		// TODO Auto-generated method stub
		return super.save(entities);
	}

	@Override
	public T save(T entity) {
		// TODO Auto-generated method stub
		return super.save(entity);
	}

	@Override
	public List<T> getAncestors(PK id) {
		List<T> ancestors = new ArrayList<T>();
		T entity = this.treeDao.findById(id).get();
		T parent = entity.getParent();
		while (parent != null) { // 
			ancestors.add(parent);
			entity = parent;
			parent = entity.getParent();
		}
		return ancestors;
	}

	@Override
	public List<T> getChildren(PK id) {
		T entity = this.treeDao.findById(id).get();
		return entity.getChildren();
	}

	@Override
	public List<T> getDescendants(PK id) {
		List<T> descendants = new ArrayList<T>();
		List<T> children = this.getChildren(id);
		if (children != null && children.size() > 0) { // 
			descendants.addAll(children);
			for (T t : children) {
				List<T> descendants2 = this.getDescendants(t.getId());
				descendants.addAll(descendants2);
			}
		}

		return descendants;
	}

	@Override
	public List<T> getRoot() {
		return this.treeDao.getRoot();
	}
}
